package com.chaos.auth.config.granter.admin;

import com.chaos.auth.api.dto.token.AdminAuthenticationToken;
import com.chaos.auth.service.userdetails.AdminByPhoneDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * @author yjp
 * @date 2024/5/30
 */
@Slf4j
@Component
public class AdminByPhoneAuthenticationProvider implements AuthenticationProvider {

    private AdminByPhoneDetailsService adminByPhoneDetailsService;
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Map<String, String> details = (Map<String, String>) authentication.getDetails();
        String phone = details.get("phone");
        Long tenantId = Long.valueOf(details.get("tenantId"));

        Assert.notNull(phone, "手机号不能为空");
        Assert.notNull(tenantId, "租户不能为空");

        UserDetails userDetails = adminByPhoneDetailsService.loadUserByPhone(phone, tenantId);
        AdminAuthenticationToken result = new AdminAuthenticationToken(userDetails);
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return AdminAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        this.passwordEncoder = passwordEncoder;
    }

    public void setUserDetailsService(AdminByPhoneDetailsService adminByPhoneDetailsService) {
        this.adminByPhoneDetailsService = adminByPhoneDetailsService;
    }
}
